action与Action类
action
代表一个Struts2请求
Action类
能够处理Struts2请求的类就是Action类,Action类具有以下特点:
- 属性的名字必须遵守与JavaBean属性名相同的命名规则,属性的类型可以是任意类型,属性名字(get set方法对应的属性名字)应当与表单发请求时对应的参数名字相对应
- 必须有一个不带参的构造函数(反射)
- 至少有一个供struts在执行这个action时调用的方法
- 同一个Action类可以包含多个action方法
- Struts为每一个Http请求创建一个新的Action实例,即Action不是单例的,是线程安全的
Action中访问WEB资源
什么是WEB资源
HttpServletRequest、HttpSession、ServletContext等原生的Servlet API
为什么需要访问WEB资源
B/S应用的Controller中必然需要访问WEB资源,比如向域对象中读写属性,读写cookie,获取realPath…
如何访问
和Servlet API解耦的方式
只能访问有限的Servlet API对象,只能访问其有限的方法(读取请求参数,读写域对象的属性,使session失效…)。
Struts2对HttpServletRequest、HttpSession、ServletContext进行了封装,构造了3个Map对象来替代这3个对象,在Action中可以直接调用HttpServletRequest、HttpServletSession、ServletContext对应的Map对应来保存和读取数据。
使用ActionContext
ActionContext是Action执行的上下文对象,在ActionContext中保存了Action执行所需要的所有对象,包括parameters、request、session、application等
获取HttpSession对应的Map对象
public Map getSession()
获取ServletContext对应的Map对象
public Map getApplication()
获取请求参数对应的Map对象
public Map getParameters()
获取HttpServletRequest对应的Map对象
public Object get(Object key)
:ActionContext类中没有提供类似getRequest()这样的方法获取HttpServletRequest对应的Map对象,要得到HttpServletRequest对应的Map对象,可以通过get()方法传递”request”参数实现
举例如下:
12345678910111213141516171819202122232425262728293031323334353637383940package com.glemontree.struts2;import java.util.Map;import com.opensymphony.xwork2.ActionContext;public class TestActionContextAction {public String execute() {// 获取ActionContext对象ActionContext actionContext = ActionContext.getContext();// 1.获取Application对应的Map,并向其中添加一个属性// 通过调用ActionContext的getApplication方法来获取application对应的Map对象Map<String, Object> applicationMap = actionContext.getApplication();// 设置属性applicationMap.put("applicationkey", "applicationValue");// 获取属性Object date = applicationMap.get("date");System.out.println("date: " + date);// 2.获取Session对应的Map,并向其中添加一个属性Map<String, Object> sessionMap = actionContext.getSession();sessionMap.put("sessionKey", "sessionValue");// 3.获取Request对应的Map,并向其中添加一个属性// ActionContext中并没有提供getRequest()方法来获取request对应的Map,需要手工调用get()方法,传入request字符串来获取Map<String, Object> requestMap = (Map<String, Object>) actionContext.get("request");requestMap.put("requestKey", "requestValue");// 4.获取请求参数对应的Map,并获取指定的参数值// 键:请求参数的名字 值:请求参数的值对应的字符串数组// 注意:getParameteres()的返回值为Map<String, Object>,而不是Map<String, String[]>// 另外,parameters这个Map只能读,不能写入数据,如果写入,但不会报错,但也不起作用Map<String, Object> parameters = actionContext.getParameters();System.out.println(((String[])parameters.get("name"))[0]);parameters.put("age", 100);return "success";}}上面这段代码主要有以下一些注意点:
- 为了在Action中获取ActionContext,需要通过ActionContext的静态方法getContext()来获取
- 对于applicationMap、sessionMap以及parameters均可以通过对应的getXXX方法获取Map对象,唯独requestMap不可以直接通过getRequest()方法来获得,而必须通过get(“request”)方法来获得requestMap
- applicationMap、sessionMap以及requestMap均可以向其中写入数据,然后从jsp中读取出来,但是parameters只能读取而不能写入数据
在jsp中读取前面写入的值的方法如下:
12345678910111213141516171819<%@ page language="java" contentType="text/html; charset=GB18030"pageEncoding="GB18030"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=GB18030"><title>Insert title here</title></head><body><h4> Test ActionContext Page</h4>application: ${applicationScope.applicationkey }<br><br>session: ${sessionScope.sessionKey }<br><br>request: ${requestScope.requestKey }<br><br>age: ${parameters.age }</body></html>注意:与范围相关的EL隐含对象包含4个:pageScope、requestScope、sessionScope以及applicationScope
实现XXXAware接口
TestAwareAction.java
1234567891011121314151617181920212223242526272829303132333435363738394041424344package com.glemontree.struts2;import java.util.Map;import org.apache.struts2.interceptor.ApplicationAware;import org.apache.struts2.interceptor.ParameterAware;import org.apache.struts2.interceptor.RequestAware;import org.apache.struts2.interceptor.SessionAware;public class TestAwareAction implements ApplicationAware, SessionAware, RequestAware, ParameterAware{public String execute() {//1.向application中加入一个属性:applicationKey2 - applicationValue2application.put("applicationKey2", "applicationValue2");System.out.println(application.get("date"));//2.从application中读取一个属性date并打印return "success";}private Map<String, Object> application;public void setApplication(Map<String, Object> application) {// TODO Auto-generated method stubthis.application = application;}public void setParameters(Map<String, String[]> arg0) {// TODO Auto-generated method stub}public void setRequest(Map<String, Object> arg0) {// TODO Auto-generated method stub}public void setSession(Map<String, Object> arg0) {// TODO Auto-generated method stub}}index.jsp
123456789101112131415161718192021<%@page import="java.util.Date"%><%@ page language="java" contentType="text/html; charset=GB18030"pageEncoding="GB18030"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=GB18030"><title>Insert title here</title></head><body><a href="TestActionContext.action?name=glemontree">Test ActionContext</a><br><br><a href="TestAware.action?name=glemontree">Test Aware</a><%if (application.getAttribute("date") == null) {application.setAttribute("date", new Date());}%></body></html>test-aware.jsp
12345678910111213<%@ page language="java" contentType="text/html; charset=GB18030"pageEncoding="GB18030"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=GB18030"><title>Insert title here</title></head><body><h4>Test Aware Page</h4>application: ${applicationScope.applicationKey2 }</body></html>
和Servlet API耦合的方式
可以访问更多的Servlet API对象且可以调用其原生的方法
- 使用ServletActionContext
- 实现ServletXXXAware接口